home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 2 / AACD 2.iso / AACD / Programming / fpc / compiler / options.pas < prev    next >
Pascal/Delphi Source File  |  1998-09-24  |  35KB  |  1,183 lines

  1. {
  2.     $Id: options.pas,v 1.3.2.2 1998/08/18 13:43:50 carl Exp $
  3.     Copyright (c) 1993-98 by the FPC development team
  4.  
  5.     Reads command line options and config files
  6.  
  7.     This program is free software; you can redistribute it and/or modify
  8.     it under the terms of the GNU General Public License as published by
  9.     the Free Software Foundation; either version 2 of the License, or
  10.     (at your option) any later version.
  11.  
  12.     This program is distributed in the hope that it will be useful,
  13.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.     GNU General Public License for more details.
  16.  
  17.     You should have received a copy of the GNU General Public License
  18.     along with this program; if not, write to the Free Software
  19.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20.  
  21.  ****************************************************************************
  22. }
  23. unit options;
  24.  
  25. interface
  26.  
  27. {$I optmsg.inc}
  28. {$I optidx.inc}
  29.  
  30. type
  31.   POption=^TOption;
  32.   TOption=object
  33.     NoPressEnter,
  34.     Logowritten : boolean;
  35.     Constructor Init;
  36.     Destructor Done;
  37.     procedure Comment(l:longint;t:toptionconst);
  38.     procedure Comment1(l:longint;t:toptionconst;const s1:string);
  39.     procedure WriteLogo;
  40.     procedure WriteInfo;
  41.     procedure WriteHelpPages;
  42.     procedure IllegalPara(const opt:string);
  43.     procedure Setbool(const opts:string;var b:boolean);
  44.     procedure interpret_proc_specific_options(const opt:string);virtual;
  45.     procedure interpret_option(const opt :string);
  46.     procedure Interpret_file(const filename : string);
  47.     procedure Read_Parameters;
  48.   end;
  49.  
  50.   procedure get_exepath;
  51.   procedure read_arguments;
  52.  
  53. implementation
  54.  
  55. uses
  56.   cobjects,globals,systems,
  57.   verbose,dos,scanner,link,verb_def,messages,os2_targ
  58. {$ifdef i386}
  59.   ,opts386
  60. {$endif}
  61. {$ifdef m68k}
  62.   ,opts68k
  63. {$endif}
  64.   ;
  65.  
  66. const
  67.   page_size = 24;
  68. {$ifdef i386}
  69.   ppccfg : string = 'pp68k.cfg';
  70. {$else}
  71.   ppccfg : string = 'pp68k.cfg';
  72. {$endif}
  73.  
  74. var
  75.   readfilename,             { read filename from the commandline ? }
  76.   read_configfile,          { read config file, set when a cfgfile is found }
  77.   target_is_set : boolean;  { do not allow contradictory target settings }
  78.   msgfilename,
  79.   param_file    : string;   { file to compile specified on the commandline }
  80.   optionmsg     : pmessage;
  81.   option        : poption;
  82.  
  83. {****************************************************************************
  84.                                  Defines
  85. ****************************************************************************}
  86.  
  87. procedure def_symbol(const s : string);
  88. begin
  89.   if s='' then
  90.    exit;
  91.   commandlinedefines.concat(new(pstring_item,init(upper(s))));
  92. end;
  93.  
  94.  
  95. procedure undef_symbol(const s : string);
  96. var
  97.   item,next : pstring_item;
  98. begin
  99.   if s='' then
  100.    exit;
  101.   item:=pstring_item(commandlinedefines.first);
  102.   while assigned(item) do
  103.    begin
  104.      if (item^.str^=s) then
  105.       begin
  106.         next:=pstring_item(item^.next);
  107.         commandlinedefines.remove(item);
  108.         item:=next;
  109.       end
  110.      else
  111.       if item<>pstring_item(item^.next) then
  112.        item:=pstring_item(item^.next)
  113.       else
  114.        break;
  115.    end;
  116. end;
  117.  
  118.  
  119. function check_symbol(const s:string):boolean;
  120. var
  121.   hp : pstring_item;
  122. begin
  123.   hp:=pstring_item(commandlinedefines.first);
  124.   while assigned(hp) do
  125.    begin
  126.      if (hp^.str^=s) then
  127.       begin
  128.         check_symbol:=true;
  129.         exit;
  130.       end;
  131.      hp:=pstring_item(hp^.next);
  132.    end;
  133.   check_symbol:=false;
  134. end;
  135.  
  136. {****************************************************************************
  137.                                  Toption
  138. ****************************************************************************}
  139.  
  140.  
  141. procedure Toption.Comment(l:longint;t:toptionconst);
  142. begin
  143.   if (Verbosity and l)<>0 then
  144.    WriteLn(optionmsg^.Get(ord(t)));
  145. end;
  146.  
  147.  
  148. procedure Toption.Comment1(l:longint;t:toptionconst;const s1:string);
  149. begin
  150.   if (Verbosity and l)<>0 then
  151.    WriteLn(optionmsg^.Get1(ord(t),s1));
  152. end;
  153.  
  154.  
  155. procedure Toption.WriteLogo;
  156. var
  157.   i : toptionconst;
  158. begin
  159.   if Logowritten then
  160.    exit;
  161.   for i:=logo_start to logo_end do
  162.    Comment1(V_Default,i,target);
  163.   Logowritten:=true;
  164. end;
  165.  
  166.  
  167. procedure Toption.WriteInfo;
  168. var
  169.   i : toptionconst;
  170. begin
  171.   for i:=info_start to info_end do
  172.    Comment(V_Default,i);
  173.   Stop;
  174. end;
  175.  
  176.  
  177. procedure Toption.WriteHelpPages;
  178.  
  179.   function PadEnd(s:string;i:longint):string;
  180.   begin
  181.     while (length(s)<i) do
  182.      s:=s+' ';
  183.     PadEnd:=s;
  184.   end;
  185.  
  186. var
  187.   lastident,
  188.   i,j,
  189.   outline,
  190.   ident,
  191.   lines : longint;
  192.   show  : boolean;
  193.   opt   : string[32];
  194.   input,
  195.   s     : string;
  196. begin
  197.   Write(paramstr(0));
  198.   Comment(V_Default,usage);
  199.   lastident:=0;
  200.   if logowritten then
  201.    lines:=3
  202.   else
  203.    lines:=1;
  204.   for i:=1 to optionhelplines do
  205.    begin
  206.    { get a line and reset }
  207.      s:=optionmsg^.Get(ord(endoptionconst)-1+i);
  208.      ident:=0;
  209.      show:=false;
  210.    { parse options }
  211.      case s[1] of
  212. {$ifdef i386}
  213.       '3',
  214. {$endif}
  215. {$ifdef m68k}
  216.       '6',
  217. {$endif}
  218.       '*' : show:=true;
  219.      end;
  220.      if show then
  221.       begin
  222.         case s[2] of
  223. {$ifdef linux}
  224.          'L',
  225. {$endif}
  226. {$ifdef os2}
  227.          'O',
  228. {$endif}
  229.          '*' : show:=true;
  230.         else
  231.          show:=false;
  232.         end;
  233.       end;
  234.    { now we may show the message or not }
  235.      if show then
  236.       begin
  237.         case s[3] of
  238.          '0' : begin
  239.                  ident:=0;
  240.                  outline:=0;
  241.                end;
  242.          '1' : begin
  243.                  ident:=2;
  244.                  outline:=7;
  245.                end;
  246.          '2' : begin
  247.                  ident:=11;
  248.                  outline:=9;
  249.                end;
  250.          '3' : begin
  251.                  ident:=21;
  252.                  outline:=6;
  253.                end;
  254.         end;
  255.         j:=pos('_',s);
  256.         opt:=Copy(s,4,j-4);
  257.         if opt='*' then
  258.          opt:=''
  259.         else
  260.          opt:=PadEnd('-'+opt,outline);
  261.         if (ident=0) and (lastident<>0) then
  262.          begin
  263.            Writeln;
  264.            inc(Lines);
  265.          end;
  266.       { page full ? }
  267.         if (lines>=page_size) then
  268.          begin
  269.            if not NoPressEnter then
  270.             begin
  271.               write('*** press enter ***');
  272.               readln(input);
  273.               if upper(input)='Q' then
  274.                stop;
  275.             end;
  276.            lines:=0;
  277.          end;
  278.         WriteLn(PadEnd('',ident)+opt+Copy(s,j+1,255));
  279.         LastIdent:=Ident;
  280.         inc(Lines);
  281.       end;
  282.    end;
  283.   stop;
  284. end;
  285.  
  286.  
  287. procedure Toption.IllegalPara(const opt:string);
  288. begin
  289.   Comment1(V_Default,illegal_para,opt);
  290.   Comment(V_Default,help_pages_para);
  291.   stop;
  292. end;
  293.  
  294.  
  295. procedure Toption.Setbool(const opts:string;var b:boolean);
  296. var
  297.   i : longint;
  298. begin
  299.   b:=true;
  300.   for i:=3 to length(opts) do
  301.    case opts[i] of
  302.     '-' : b:=false;
  303.     '+' : b:=true;
  304.    else
  305.     IllegalPara(opts);
  306.    end;
  307. end;
  308.  
  309.  
  310. procedure TOption.interpret_proc_specific_options(const opt:string);
  311. begin
  312. end;
  313.  
  314.  
  315. procedure TOption.interpret_option(const opt:string);
  316. var
  317.   code : word;
  318.   c    : char;
  319.   more : string;
  320.   j    : longint;
  321. begin
  322.   if opt='' then
  323.    exit;
  324.   case opt[1] of
  325.  '-' : begin
  326.          more:=Copy(opt,3,255);
  327.          case opt[2] of
  328.               '?' : WriteHelpPages;
  329.               'h' : begin
  330.                       NoPressEnter:=true;
  331.                       WriteHelpPages;
  332.                     end;
  333.               'a' : writeasmfile:=true;
  334. {$ifdef tp}
  335.               'b' : setbool(opt,use_big);
  336. {$endif}
  337.               'B' : if more='' then
  338.                      do_build:=true
  339.                     else
  340.                      IllegalPara(opt);
  341.               'C' : begin
  342.                       for j:=1 to length(more) do
  343.                        case more[j] of
  344.                         'a','e' : ;
  345.                             'h' : begin
  346.                                     val(copy(more,j+1,length(more)-j),heapsize,code);
  347.                                     if (code<>0) or (heapsize>=67107840) or (heapsize<1024) then
  348.                                      IllegalPara(opt);
  349.                                     break;
  350.                                   end;
  351.                             'i' : initswitches:=initswitches+[cs_iocheck];
  352.                             'n' : initswitches:=initswitches+[cs_no_linking];
  353.                             'o' : initswitches:=initswitches+[cs_check_overflow];
  354.                             'r' : initswitches:=initswitches+[cs_rangechecking];
  355.                             's' : begin
  356.                                     val(copy(more,j+1,length(more)-j),stacksize,code);
  357.                                     if (code<>0) or (stacksize>=67107840) or (stacksize<1024) then
  358.                                      IllegalPara(opt);
  359.                                     break;
  360.                                   end;
  361.                             { this is not a very good choice for that }
  362.                             't' : initswitches:=initswitches+[cs_check_stack];
  363.                             'D' : begin
  364.                                     initswitches:=initswitches-[cs_link_static];
  365.                                     initswitches:=initswitches+[cs_link_dynamic];
  366.                                   end;
  367.                             'S' : begin
  368.                                     initswitches:=initswitches-[cs_link_dynamic];
  369.                                     initswitches:=initswitches+[cs_link_static];
  370.                                   end;
  371.                        else IllegalPara(opt);
  372.                        end;
  373.                     end;
  374.               'd' : def_symbol(more);
  375. {$ifdef os2}
  376.               'D' : begin
  377.                       for j:=1 to length(more) do
  378.                        case more[j] of
  379.                         'd' : begin
  380.                                 description:=Copy(more,j+1,255);
  381.                                 break;
  382.                               end;
  383.                         'o' : begin
  384.                                 if target_info.target<>target_OS2 then
  385.                                  Comment(v_warning,def_only_for_os2);
  386.                                 gendeffile:=true;
  387.                               end;
  388.                         'w' : genpm:=true;
  389.                        else IllegalPara(opt);
  390.                        end;
  391.                     end;
  392. {$endif}
  393.               'E' : initswitches:=initswitches+[cs_no_linking];
  394.               'F' : begin
  395.                       c:=more[1];
  396.                       Delete(more,1,1);
  397.                       case c of
  398.                        'e' : SetRedirectFile(More);
  399.                        'r' : Msgfilename:=More;
  400.                        'i' : AddPathToList(includesearchpath,More,false);
  401.                        'l' : AddPathToList(Linker.librarysearchpath,More,false);
  402.                        'u' : AddPathToList(unitsearchpath,More,false);
  403. {$ifdef linux}
  404.                        'g' : Linker.gcclibrarypath:=More;
  405.                        'L' : if More<>'' then
  406.                               Linker.DynamicLinker:=More
  407.                              else
  408.                               IllegalPara(opt);
  409. {$endif}
  410.                       else IllegalPara(opt);
  411.                       end;
  412.                     end;
  413.               'g' : begin
  414.                       initswitches:=initswitches+[cs_debuginfo];
  415.                       for j:=1 to length(more) do
  416.                        case more[j] of
  417. {$ifdef UseBrowser}
  418.                         'b' : use_browser:=true;
  419. {$endif UseBrowser}
  420. {$ifdef GDB}
  421.                         'g' : use_gsym:=true;
  422.                         'd' : use_dbx:=true;
  423.                         'p' : initswitches:=initswitches+[cs_profile];
  424. {$endif GDB}
  425.                        else IllegalPara(opt);
  426.                        end;
  427.                     end;
  428.               'i' : WriteInfo;
  429.               'I' : AddPathToList(includesearchpath,More,false);
  430.               'l' : if more='' then
  431.                      WriteLogo
  432.                     else
  433.                      IllegalPara(opt);
  434.               'k' : if more<>'' then
  435.                      Linker.LinkOptions:=Linker.LinkOptions+' '+More
  436.                     else
  437.                      IllegalPara(opt);
  438.               'L' : begin
  439.                       if length(More)<>1 then
  440.                        IllegalPara(opt);
  441.                       case More[1] of
  442.                        'E' : language:='E';
  443.                        'D' : language:='D';
  444.                       else IllegalPara(opt);
  445.                       end
  446.                     end;
  447.               'n' : if More='' then
  448.                      read_configfile:=false
  449.                     else
  450.                      IllegalPara(opt);
  451.               'o' : if More<>'' then
  452.                      Linker.SetFileName(More)
  453.                     else
  454.                      IllegalPara(opt);
  455.               'p' :
  456. {$ifdef Splitheap}
  457.                   if length(opt)=2 then
  458.                      testsplit:=true
  459.                     else
  460. {$endif Splitheap}
  461.                    begin
  462.                      case more[1] of
  463.                       'g' : initswitches:=initswitches+[cs_profile];
  464.                      else
  465.                       IllegalPara(opt);
  466.                      end;
  467.                    end;
  468. {$ifdef linux}
  469.               'P' : use_pipe:=true;
  470. {$endif}
  471.               's' : begin
  472.                       setbool(opt,externasm);
  473.                       setbool(opt,externlink);
  474.                     end;
  475.               'S' : begin
  476.                       for j:=1 to length(more) do
  477.                        case more[j] of
  478.                         'c' : c_like_operators:=true;
  479.                         'd' : dispose_asm_lists:=true;
  480.                         'e' : MaxErrorCount:=1;
  481.                         'g' : initswitches:=initswitches+[cs_support_goto];
  482.                         'i' : support_inline:=true;
  483.                         'm' : begin
  484.                               { init macro buffer }
  485.                                 if not(support_macros) then
  486.                                  new(macrobuffer);
  487.                                 support_macros:=true;
  488.                               end;
  489.                         'o' : initswitches:=initswitches+[cs_tp_compatible];
  490.                         't' : initswitches:=initswitches+[cs_static_keyword];
  491.                         '2' : begin
  492.                                  initswitches:=initswitches+[cs_delphi2_compatible];
  493.                                  initswitches:=initswitches+[cs_load_objpas_unit]
  494.                               end;
  495.                         's' : initswitches:=initswitches+[cs_checkconsname];
  496.                        else IllegalPara(opt);
  497.                        end;
  498.                     end;
  499.               'T' : begin
  500.                       more:=Upper(More);
  501.                       if not target_is_set then
  502.                        begin
  503.                        { her we should undefine the default target }
  504.                          undef_symbol(target_info.short_name);
  505.                          if not(set_string_target(More)) then
  506.                           IllegalPara(opt);
  507.                          def_symbol(target_info.short_name);
  508.                          target_is_set:=true;
  509.                        end
  510.                       else
  511.                        if More<>target_info.short_name then
  512.                         Comment1(V_Warning,target_is_already_set,target_info.short_name);
  513.                     end;
  514.               'u' : undef_symbol(upper(More));
  515.               'U' : begin
  516.                       for j:=1 to length(more) do
  517.                        case more[j] of
  518.                         'l' : begin
  519.                                 if j<length(opt) then
  520.                                  case opt[j+1] of
  521.                                   'd' : begin
  522.                                           initswitches:=initswitches+[cs_unit_to_lib];
  523.                                           if target_info.target in [target_GO32V1,target_GO32V2] then
  524.                                            Comment(V_Warning,no_shared_lib_under_dos)
  525.                                           else
  526.                                            initswitches:=initswitches+[cs_shared_lib];
  527.                                          end;
  528.                                    's' : initswitches:=initswitches+[cs_unit_to_lib];
  529.                                   else IllegalPara(opt);
  530.                                   end
  531.                                  else
  532.                                   IllegalPara(opt);
  533.                               end;
  534.                         's' : initswitches:=initswitches+[cs_compilesystem];
  535.                         'n' : initswitches:=initswitches+[cs_check_unit_name];
  536.                         { 'o' : initswitches:=initswitches+[cs_load_objpas_unit]; }
  537.                         'p' : begin
  538.                                 AddPathToList(unitsearchpath,Copy(More,j+1,255),false);
  539.                                 break;
  540.                               end;
  541.                        else IllegalPara(opt);
  542.                        end;
  543.                     end;
  544.               'v' : if not setverbosity(More) then
  545.                      IllegalPara(opt);
  546.               'X' : begin
  547.                       for j:=1 to length(More) do
  548.                        case More[j] of
  549. {$ifdef linux}
  550.                         'c' : Linker.LinkToC:=true;
  551. {$endif}
  552.                         's' : Linker.Strip:=true;
  553.                        else IllegalPara(opt);
  554.                        end;
  555.                     end;
  556.        { give processor specific options a chance }
  557.          else
  558.           interpret_proc_specific_options(opt);
  559.          end;
  560.        end;
  561.  '@' : begin
  562.          Comment(V_Error,no_nested_response_file);
  563.          Stop;
  564.        end;
  565.   else
  566.    begin
  567.      if readfilename then
  568.       begin
  569.         if (length(param_file)<>0) then
  570.          Comment(v_error,only_one_source_support);
  571.         param_file:=opt;
  572.       end;
  573.    end;
  574.   end;
  575. end;
  576.  
  577.  
  578. procedure Toption.Interpret_file(const filename : string);
  579.  
  580.   procedure RemoveSep(var fn:string);
  581.   var
  582.     i : longint;
  583.   begin
  584.     i:=0;
  585.     while (i<length(fn)) and (fn[i+1] in [',',' ',#9]) do
  586.      inc(i);
  587.     Delete(fn,1,i);
  588.   end;
  589.  
  590.   function GetName(var fn:string):string;
  591.   var
  592.     i : longint;
  593.   begin
  594.     i:=0;
  595.     while (i<length(fn)) and (fn[i+1] in ['A'..'Z','0'..'9','_','-']) do
  596.      inc(i);
  597.     GetName:=Copy(fn,1,i);
  598.     Delete(fn,1,i);
  599.   end;
  600.  
  601. const
  602.   maxlevel=16;
  603. var
  604.   f     : text;
  605.   s,
  606.   opts  : string;
  607.   skip  : array[0..maxlevel-1] of boolean;
  608.   level : byte;
  609. begin
  610.   assign(f,filename);
  611.   {$I-}
  612.    reset(f);
  613.   {$I+}
  614.   if ioresult<>0 then
  615.    begin
  616.      Comment1(V_Error,unable_open_file,filename);
  617.      exit;
  618.    end;
  619.   fillchar(skip,sizeof(skip),0);
  620.   level:=0;
  621.   while not eof(f) do
  622.    begin
  623.      readln(f,opts);
  624.      RemoveSep(opts);
  625.      if (opts<>'') then
  626.       begin
  627.         if opts[1]='#' then
  628.          begin
  629.            Delete(opts,1,1);
  630.            s:=upper(GetName(opts));
  631.            if (s='SECTION') then
  632.             begin
  633.               RemoveSep(opts);
  634.               s:=upper(GetName(opts));
  635.               if level=0 then
  636.                skip[level]:=not (check_symbol(s) or (s='COMMON'));
  637.             end
  638.            else
  639.             if (s='IFDEF') then
  640.              begin
  641.                RemoveSep(opts);
  642.                if Level>=maxlevel then
  643.                 begin
  644.                   Comment(V_Fatal,too_many_ifdef);
  645.                   stop;
  646.                 end;
  647.                inc(Level);
  648.                skip[level]:=(skip[level-1] or (not check_symbol(upper(GetName(opts)))));
  649.              end
  650.            else
  651.             if (s='IFNDEF') then
  652.              begin
  653.                RemoveSep(opts);
  654.                if Level>=maxlevel then
  655.                 begin
  656.                   Comment(V_Fatal,too_many_ifdef);
  657.                   stop;
  658.                 end;
  659.                inc(Level);
  660.                skip[level]:=(skip[level-1] or (check_symbol(upper(GetName(opts)))));
  661.              end
  662.            else
  663.             if (s='ELSE') then
  664.              skip[level]:=skip[level-1] or (not skip[level])
  665.            else
  666.             if (s='ENDIF') then
  667.              begin
  668.                skip[level]:=false;
  669.                if Level=0 then
  670.                 begin
  671.                   Comment(V_Fatal,too_many_endif);
  672.                   stop;
  673.                 end;
  674.                dec(level);
  675.              end
  676.            else
  677.             if (not skip[level]) then
  678.              begin
  679.                if (s='DEFINE') then
  680.                 begin
  681.                   RemoveSep(opts);
  682.                   def_symbol(upper(GetName(opts)));
  683.                 end
  684.               else
  685.                if (s='UNDEF') then
  686.                 begin
  687.                   RemoveSep(opts);
  688.                   undef_symbol(upper(GetName(opts)));
  689.                 end
  690.               else
  691.                if (s='WRITE') then
  692.                 begin
  693.                   Delete(opts,1,1);
  694.                   WriteLn(opts);
  695.                 end
  696.               else
  697.                if (s='INCLUDE') then
  698.                 begin
  699.                   Delete(opts,1,1);
  700.                   Interpret_file(opts);
  701.                 end;
  702.             end;
  703.          end
  704.         else
  705.          begin
  706.            if (not skip[level]) and (opts[1]='-') then
  707.             interpret_option(opts)
  708.          end;
  709.       end;
  710.    end;
  711.   if Level>0 then
  712.    Comment(V_Warning,too_less_endif);
  713.   Close(f);
  714. end;
  715.  
  716.  
  717. procedure toption.read_parameters;
  718. var
  719.   opts       : string;
  720.   paramindex : longint;
  721. begin
  722.   paramindex:=0;
  723.   while paramindex<paramcount do
  724.    begin
  725.      inc(paramindex);
  726.      opts:=paramstr(paramindex);
  727.      if opts[1]='@' then
  728.       begin
  729.         Delete(opts,1,1);
  730.         Comment1(V_Info,reading_further_from,opts);
  731.         interpret_file(opts);
  732.       end
  733.      else
  734.       interpret_option(opts);
  735.    end;
  736. end;
  737.  
  738.  
  739. constructor TOption.Init;
  740. begin
  741.   LogoWritten:=false;
  742.   NoPressEnter:=false;
  743. end;
  744.  
  745.  
  746. destructor TOption.Done;
  747. begin
  748. end;
  749.  
  750.  
  751. {****************************************************************************
  752.                               Callable Routines
  753. ****************************************************************************}
  754.  
  755. procedure get_exepath;
  756. var
  757.   hs1 : namestr;
  758.   hs2 : extstr;
  759. begin
  760.   exepath:=dos.getenv('PPC_EXEC_PATH');
  761.   if exepath='' then
  762.    fsplit(FixFileName(paramstr(0)),exepath,hs1,hs2);
  763. {$ifdef linux}
  764.   if exepath='' then
  765.    fsearch(hs1,dos.getenv('PATH'));
  766.    exepath:='/usr/bin/';
  767. {$endif}
  768.   exepath:=FixPath(exepath);
  769. end;
  770.  
  771.  
  772. procedure read_arguments;
  773. var
  774.   configpath : pathstr;
  775.   option     : poption;
  776. begin
  777. {$ifdef i386}
  778.   option:=new(poption386,Init);
  779. {$else}
  780.   {$ifdef m68k}
  781.     option:=new(poption68k,Init);
  782.   {$else}
  783.     option:=new(poption,Init);
  784.   {$endif}
  785. {$endif}
  786. { Load messages }
  787.   optionmsg:=new(pmessage,Init(@optiontxt,ord(endoptionconst)+optionhelplines));
  788.  
  789.   if paramcount=0 then
  790.    Option^.WriteHelpPages;
  791.  
  792. { default defines }
  793.   def_symbol(target_info.short_name);
  794.   def_symbol('FPK');
  795.   def_symbol('FPC');
  796.   def_symbol('VER'+version_nr);
  797.   def_symbol('VER'+version_nr+'_'+release_nr);
  798.   def_symbol('VER'+version_nr+'_'+release_nr+'_'+patch_nr);
  799.   def_symbol('NEW_ERRORS'); { Temporary, until things settle down }
  800. { some stuff for TP compatibility }
  801. {$ifdef i386}
  802.   def_symbol('CPU86');
  803.   def_symbol('CPU87');
  804.   if (target_info.target in [target_GO32V1,target_GO32V2]) then
  805.    def_symbol('DPMI'); { MSDOS is not defined in BP whewn target is DPMI }
  806. {$endif}
  807. {$ifdef m68k}
  808.   def_symbol('CPU68');
  809. {$endif}
  810.  
  811.   msgfilename:=dos.getenv('PPC_ERROR_FILE');
  812. {$ifdef extern_msg}
  813.   if msgfilename='' then
  814.    msgfilename:=exepath+'errore.msg';
  815. {$endif}
  816.  
  817.   { Order to read ppc386.cfg:
  818.      1 - current dir
  819.      2 - configpath
  820.      3 - compiler path }
  821.   configpath:=FixPath(dos.getenv('PPC_CONFIG_PATH'));
  822. {$ifdef linux}
  823.   if configpath='' then
  824.    configpath:='/etc/';
  825. {$endif}
  826.   read_configfile:=true;
  827.   if not FileExists(ppccfg) then
  828.    begin
  829. {$ifdef linux}
  830.      if (dos.getenv('HOME')<>'') and FileExists(FixPath(dos.getenv('HOME'))+'.'+ppccfg) then
  831.       ppccfg:=FixPath(dos.getenv('HOME'))+'.'+ppccfg
  832.      else
  833. {$endif}
  834.       if FileExists(configpath+ppccfg) then
  835.        ppccfg:=configpath+ppccfg
  836.      else
  837.       if FileExists(exepath+ppccfg) then
  838.        ppccfg:=exepath+ppccfg
  839.      else
  840.       read_configfile:=false;
  841.    end;
  842.  
  843. { Read commandline and configfile }
  844.   target_is_set:=false;
  845.   param_file:='';
  846.   readfilename:=true;
  847.  
  848.   option^.read_parameters;
  849.   if read_configfile then
  850.    begin
  851. {$ifdef EXTDEBUG}
  852.      comment(V_Error,'read config file  #'+ppccfg+'#');
  853. {$endif EXTDEBUG}
  854.      option^.interpret_file(ppccfg);
  855.    { Reread parameters to overwrite the options }
  856.      readfilename:=false;
  857.      option^.read_parameters;
  858.    end;
  859.   commandline_output_format:=output_format;
  860.  
  861. { Check file to compile }
  862.   if param_file='' then
  863.    begin
  864.      option^.Comment(v_error,no_source_found);
  865.      Stop;
  866.    end;
  867. {$ifndef linux}
  868.   param_file:=FixFileName(param_file);
  869. {$endif}
  870.   fsplit(param_file,inputdir,inputfile,inputextension);
  871.   if inputextension='' then
  872.    begin
  873.      if FileExists(inputdir+inputfile+target_info.sourceext) then
  874.       inputextension:=target_info.sourceext
  875.      else
  876.       if FileExists(inputdir+inputfile+target_info.pasext) then
  877.        inputextension:=target_info.pasext;
  878.    end;
  879.  
  880. { add unit environment and exepath to the unit search path }
  881.   if inputdir<>'' then
  882.    AddPathToList(Unitsearchpath,inputdir,true);
  883.   AddPathToList(UnitSearchPath,dos.getenv(target_info.unit_env),false);
  884.   AddPathToList(UnitSearchPath,ExePath,false);
  885. { Add Current Directory as the first path to search }
  886.   AddPathToList(unitsearchpath,'.',true);
  887.   AddPathToList(objectsearchpath,'.',true);
  888.   AddPathToList(includesearchpath,'.',true);
  889.  
  890.   if msgfilename<>'' then
  891.    LoadMsgFile(msgfilename);
  892.  
  893.   if gendeffile then
  894.    write_def_file;
  895.  
  896.   dispose(optionmsg,Done);
  897.   dispose(option,Done);
  898. end;
  899.  
  900.  
  901. end.
  902. {
  903.   $Log: options.pas,v $
  904.   Revision 1.3.2.2  1998/08/18 13:43:50  carl
  905.     + Added -Sd switch
  906.  
  907.   Revision 1.3.2.1  1998/04/08 12:31:32  peter
  908.     + .ppc386.cfg and #INCLUDE support
  909.  
  910.   Revision 1.3  1998/03/28 23:09:56  florian
  911.     * secondin bugfix (m68k and i386)
  912.     * overflow checking bugfix (m68k and i386) -- pretty useless in
  913.       secondadd, since everything is done using 32-bit
  914.     * loading pointer to routines hopefully fixed (m68k)
  915.     * flags problem with calls to RTL internal routines fixed (still strcmp
  916.       to fix) (m68k)
  917.     * #ELSE was still incorrect (didn't take care of the previous level)
  918.     * problem with filenames in the command line solved
  919.     * problem with mangledname solved
  920.     * linking name problem solved (was case insensitive)
  921.     * double id problem and potential crash solved
  922.     * stop after first error
  923.     * and=>test problem removed
  924.     * correct read for all float types
  925.     * 2 sigsegv fixes and a cosmetic fix for Internal Error
  926.     * push/pop is now correct optimized (=> mov (%esp),reg)
  927.  
  928.   Revision 1.2  1998/03/26 11:18:30  florian
  929.     - switch -Sa removed
  930.     - support of a:=b:=0 removed
  931.  
  932.   Revision 1.1.1.1  1998/03/25 11:18:16  root
  933.   * Restored version
  934.  
  935.   Revision 1.52  1998/03/22 12:43:32  florian
  936.   *** empty log message ***
  937.  
  938.   Revision 1.51  1998/03/16 22:42:20  florian
  939.     * some fixes of Peter applied:
  940.       ofs problem, profiler support
  941.  
  942.   Revision 1.50  2036/02/07 09:26:56  florian
  943.     * more fixes to get -Ox work
  944.  
  945.   Revision 1.49  1998/03/10 16:27:39  pierre
  946.     * better line info in stabs debug
  947.     * symtabletype and lexlevel separated into two fields of tsymtable
  948.     + ifdef MAKELIB for direct library output, not complete
  949.     + ifdef CHAINPROCSYMS for overloaded seach across units, not fully
  950.       working
  951.     + ifdef TESTFUNCRET for setting func result in underfunction, not
  952.       working
  953.  
  954.   Revision 1.48  1998/03/10 12:55:08  peter
  955.     + preprocessor for the configfile
  956.     * fixed options helppage
  957.     * -h shows the helppages without waiting
  958.  
  959.   Revision 1.47  1998/03/10 01:17:20  peter
  960.     * all files have the same header
  961.     * messages are fully implemented, EXTDEBUG uses Comment()
  962.     + AG... files for the Assembler generation
  963.  
  964.   Revision 1.46  1998/03/09 16:47:56  jonas
  965.     * the -Xs option works again
  966.  
  967.   Revision 1.45  1998/03/09 12:58:11  peter
  968.     * FWait warning is only showed for Go32V2 and $E+
  969.     * opcode tables moved to i386.pas/m68k.pas to reduce circular uses (and
  970.       for m68k the same tables are removed)
  971.     + $E for i386
  972.  
  973.   Revision 1.44  1998/03/06 01:08:59  peter
  974.     * removed the conflicts that had occured
  975.  
  976.   Revision 1.43  1998/03/06 00:52:29  peter
  977.     * replaced all old messages from errore.msg, only ExtDebug and some
  978.       Comment() calls are left
  979.     * fixed options.pas
  980.  
  981.   Revision 1.42  1998/03/05 22:41:29  florian
  982.     + missing constructor to options object added
  983.  
  984.   Revision 1.41  1998/03/05 02:44:13  peter
  985.     * options cleanup and use of .msg file
  986.  
  987.   Revision 1.40  1998/03/04 17:33:46  michael
  988.   + Changed ifdef FPK to ifdef FPC
  989.  
  990.   Revision 1.39  1998/03/04 14:18:59  michael
  991.   * modified messaging system
  992.  
  993.   Revision 1.38  1998/03/02 16:02:03  peter
  994.     * new style messages for pp.pas
  995.     * cleanup of pp.pas
  996.  
  997.   Revision 1.37  1998/03/02 01:48:45  peter
  998.     * renamed target_DOS to target_GO32V1
  999.     + new verbose system, merged old errors and verbose units into one new
  1000.       verbose.pas, so errors.pas is obsolete
  1001.  
  1002.   Revision 1.36  1998/03/01 22:46:13  florian
  1003.     + some win95 linking stuff
  1004.     * a couple of bugs fixed:
  1005.       bug0055,bug0058,bug0059,bug0064,bug0072,bug0093,bug0095,bug0098
  1006.  
  1007.   Revision 1.35  1998/02/22 23:56:21  peter
  1008.     * fixed some strange syntax errors
  1009.  
  1010.   Revision 1.34  1998/02/22 21:55:45  carl
  1011.     + added Ct switch display
  1012.  
  1013.   Revision 1.33  1998/02/18 08:56:26  michael
  1014.   * GccLibraryPath and Dynamiclinker are linux only
  1015.  
  1016.   Revision 1.32  1998/02/17 21:20:51  peter
  1017.     + Script unit
  1018.     + __EXIT is called again to exit a program
  1019.     - target_info.link/assembler calls
  1020.     * linking works again for dos
  1021.     * optimized a few filehandling functions
  1022.     * fixed stabs generation for procedures
  1023.  
  1024.   Revision 1.31  1998/02/16 13:46:41  michael
  1025.   + Further integration of linker object:
  1026.     - all options pertaining to linking go directly to linker object
  1027.     - removed redundant variables/procedures, especially in OS_TARG...
  1028.  
  1029.   Revision 1.30  1998/02/14 01:45:22  peter
  1030.     * more fixes
  1031.     - pmode target is removed
  1032.     - search_as_ld is removed, this is done in the link.pas/assemble.pas
  1033.     + findexe() to search for an executable (linker,assembler,binder)
  1034.  
  1035.   Revision 1.29  1998/02/13 10:35:11  daniel
  1036.   * Made Motorola version compilable.
  1037.   * Fixed optimizer
  1038.  
  1039.   Revision 1.28  1998/02/12 11:50:14  daniel
  1040.   Yes! Finally! After three retries, my patch!
  1041.  
  1042.   Changes:
  1043.  
  1044.   Complete rewrite of psub.pas.
  1045.   Added support for DLL's.
  1046.   Compiler requires less memory.
  1047.   Platform units for each platform.
  1048.  
  1049.   Revision 1.27  1998/02/08 01:59:33  peter
  1050.     + option -P to allow the use of pipe for assembly output
  1051.  
  1052.   Revision 1.26  1998/02/07 09:39:22  florian
  1053.     * correct handling of in_main
  1054.     + $D,$T,$X,$V like tp
  1055.  
  1056.   Revision 1.25  1998/02/02 00:55:33  peter
  1057.     * defdatei -> deffile and some german comments to english
  1058.     * search() accepts : as seperater under linux
  1059.     * search for ppc.cfg doesn't open a file (and let it open)
  1060.     * reorganize the reading of parameters/file a bit
  1061.     * all the PPC_ environments are now for all platforms
  1062.  
  1063.   Revision 1.24  1998/02/01 22:41:05  florian
  1064.     * clean up
  1065.     + system.assigned([class])
  1066.     + system.assigned([class of xxxx])
  1067.     * first fixes of as and is-operator
  1068.  
  1069.   Revision 1.23  1998/01/30 20:00:13  carl
  1070.     * Missing Target OS info
  1071.  
  1072.   Revision 1.22  1998/01/30 17:38:36  carl
  1073.     * Line too long errors under Borland Pascal
  1074.  
  1075.   Revision 1.21  1998/01/28 13:48:40  michael
  1076.   + Initial implementation for making libs from within FPC. Not tested, as compiler does not run
  1077.  
  1078.   Revision 1.20  1998/01/25 18:45:44  peter
  1079.     + Search for as and ld at startup
  1080.     + source_info works the same as target_info
  1081.     + externlink allows only external linking
  1082.  
  1083.   Revision 1.19  1998/01/23 22:19:18  michael
  1084.   + Implemented setting of dynamic linker name (linux only).
  1085.     Declared Make_library
  1086.     -Fd switch sets linker (linux only)
  1087.   * Reinstated -E option of Pierre
  1088.  
  1089.   Revision 1.18  1998/01/23 17:55:08  michael
  1090.   + Moved linking stage to it's own unit (link.pas)
  1091.     Incorporated Pierres changes, but removed -E switch
  1092.     switch for not linking is now -Cn instead of -E
  1093.  
  1094.   Revision 1.17  1998/01/23 17:12:13  pierre
  1095.     * added some improvements for as and ld :
  1096.       - doserror and dosexitcode treated separately
  1097.       - PATH searched if doserror=2
  1098.     + start of long and ansi string (far from complete)
  1099.       in conditionnal UseLongString and UseAnsiString
  1100.     * options.pas cleaned (some variables shifted to globals)gl
  1101.  
  1102.   Revision 1.16  1998/01/22 14:47:11  michael
  1103.   + Reinstated linker options as -k option. How did they dissapear ?
  1104.  
  1105.   Revision 1.15  1998/01/22 08:57:53  peter
  1106.     + added target_info.pasext and target_info.libext
  1107.  
  1108.   Revision 1.14  1998/01/19 10:49:09  michael
  1109.   * set library stuff only for i386, not m68k
  1110.  
  1111.   Revision 1.13  1998/01/17 22:07:40  florian
  1112.     * -Xs is also valid for DOS target
  1113.  
  1114.   Revision 1.12  1998/01/17 01:57:34  michael
  1115.   + Start of shared library support. First working version.
  1116.  
  1117.   Revision 1.11  1998/01/16 22:41:27  michael
  1118.   * restored lost changes by last commit
  1119.  
  1120.   Revision 1.10  1998/01/16 12:52:11  michael
  1121.   + Path treatment and file searching should now be more or less in their
  1122.     definite form:
  1123.     - Using now modified AddPathToList everywhere.
  1124.     - File Searching mechanism is uniform for all files.
  1125.     - Include path is working now !!
  1126.     All fixes by Peter Vreman. Tested with remake3 target.
  1127.  
  1128.   Revision 1.8  1998/01/13 17:13:07  michael
  1129.   * File time handling and file searching is now done in an OS-independent way,
  1130.     using the new file treating functions in globals.pas.
  1131.  
  1132.   Revision 1.7  1998/01/12 01:07:14  michael
  1133.   * config file is now read in correct order (By Peter Vreman)
  1134.  
  1135.   Revision 1.6  1998/01/11 03:41:59  carl
  1136.   + added OS for m68k target / changed config fname under m68k
  1137.  
  1138.   Revision 1.5  1998/01/08 17:01:14  carl
  1139.   * def_symbol(`MSDOS`) removed since in TP in DPMI mode this symbol is not
  1140.   defined.
  1141.  
  1142.   Revision 1.4  1998/01/07 00:16:52  michael
  1143.   Restored released version (plus fixes) as current
  1144.  
  1145.   Revision 1.3  1997/12/14 22:43:19  florian
  1146.     + command line switch -Xs for DOS (passes -s to the linker to strip symbols from
  1147.       executable)
  1148.     * some changes of Carl-Eric implemented
  1149.  
  1150.   Revision 1.2  1997/11/28 18:14:38  pierre
  1151.    working version with several bug fixes
  1152.  
  1153.   Revision 1.1.1.1  1997/11/27 08:32:57  michael
  1154.   FPC Compiler CVS start
  1155.  
  1156.  
  1157.   Pre-CVS log:
  1158.  
  1159.   CEC   Carl-Eric Codere
  1160.   FK    Florian Klaempfl
  1161.   PM    Pierre Muller
  1162.   +     feature added
  1163.   -     removed
  1164.   *     bug fixed or changed
  1165.  
  1166.   History:
  1167.       september 1997:
  1168.          * order of reading changed:
  1169.            first read command line args,
  1170.            read ppc386.cfg at last
  1171.            finally read command line again.
  1172.            this is necessary to read the right sections in ppc386.cfg (PM)
  1173.       22th september 1997:
  1174.          * changed switch -So to TP compatibilty
  1175.          + switch -S2 for Delphi compatibilty    (FK)
  1176.       15th october 1997:
  1177.          + added switch -St to allow static keyword in objects (PM)
  1178.       5th november 1997:
  1179.          + added -n to disable ppc386.cfg reading (PM)
  1180.       20th november 1997:
  1181.          + default symbols moved from parser.pas to here (PM)
  1182. }
  1183.